﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ServiceModel.DomainServices.Server;
using System.Web;
using Rio.Flow.Business.Repository;
using NetBay.Core.BusinessEntities;
using NetBay.Core.BusinessEntities.Workflow;
using Rio.Applications.Web.RioWCFWorkflow;
using NetBay.Core.BusinessEntities.Workflow.Rules;

namespace Rio.Applications.Web.Services
{
    public partial class BusinessEntitiesDomainService : DomainService
    {
        #region Workflow definition

        /// <summary>
        /// Workflow opened
        /// </summary>
        /// <param name="wkfDefinitionId">The WKF definition id.</param>
        [Invoke]
        public void WorkflowOpened(long wkfDefinitionId)
        {
            try
            {
                WorkflowController.WorkflowOpened(wkfDefinitionId);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in WorkflowOpened : " + ex.ToString());
            }
        }

        /// <summary>
        /// Returns all definitions
        /// </summary>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowDefinition> GetWorkflowDefinitions()
        {
            var l_oRet = new List<WorkflowDefinition>();
            try
            {
                l_oRet = WorkflowDefinitionRepository.GetWorkflowDefinitions();
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowDefinition("Exception in GetWorkflowDefinitions : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowDefinitions : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Returns definition by this id
        /// </summary>
        /// <param name="wkfDefId">Definition identifier</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowDefinition> GetWorkflowDefinitionById(long wkfDefId)
        {
            var l_oRet = new List<WorkflowDefinition>();
            try
            {
                l_oRet.Add(WorkflowDefinitionRepository.GetWorkflowDefinitionById(wkfDefId));
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowDefinition("Exception in GetWorkflowDefinitionsById : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowDefinitionsById : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Returns definition by this name
        /// </summary>
        /// <param name="wkfDefName">Definition name</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowDefinition> GetWorkflowDefinitionByName(string wkfDefName)
        {
            var l_oRet = new List<WorkflowDefinition>();
            try
            {
                l_oRet.Add(WorkflowDefinitionRepository.GetWorkflowDefinitionByName(wkfDefName));
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowDefinition("Exception in GetWorkflowDefinitionByName : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowDefinitionByName : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Returns all definitions
        /// </summary>
        /// <param name="folderTypeId">Folder type identifier</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowDefinition> GetWorkflowDefinitionsByFolderTypeId(long folderTypeId)
        {
            var l_oRet = new List<WorkflowDefinition>();
            try
            {
                l_oRet = WorkflowDefinitionRepository.GetWorkflowDefinitionsByFolderTypeId(folderTypeId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowDefinition("Exception in GetWorkflowDefinitionsByFolderTypeId : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowDefinitionsByFolderTypeId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Delete a definition
        /// </summary>
        /// <param name="wkfDefId">Definition identifier</param>
        /// <returns></returns>
        [Invoke]
        public ReturnBoolean DeleteDefinition(long wkfDefId)
        {
            ReturnBoolean l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowDefinitionRepository.DeleteDefinition(wkfDefId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in DeleteDefinition : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }

            return l_oRet;
        }

        /// <summary>
        /// Deactivate a definition
        /// </summary>
        /// <param name="wkfDefId">Definition identifier</param>
        /// <param name="deactivationDate">The deactivation date.</param>
        /// <returns></returns>
        [Invoke]
        public ReturnBoolean DeactivateDefinition(long wkfDefId, DateTime deactivationDate)
        {
            ReturnBoolean l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowDefinitionRepository.DeactivateDefinition(wkfDefId, deactivationDate);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in DeactivateDefinition : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }

            return l_oRet;
        }

        /// <summary>
        /// Add a definition With groups identifiers as receivers.
        /// </summary>
        /// <param name="definition">The definition</param>
        /// <param name="actions">List of availables actions for the definition</param>
        /// <param name="conditions">List of availables conditions for the definition</param>
        /// <param name="receiverIndexId">Index INdentifier</param>
        /// <param name="keepChilds">if set to <c>true</c> [keep childs].</param>
        /// <returns>
        /// True if ok
        /// </returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean AddWorkflowDefinitionWithIndex(WorkflowDefinition definition, Dictionary<long, bool> actions, List<long> conditions, long receiverIndexId, bool keepChilds = true)
        {
            ReturnBoolean l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowDefinitionRepository.AddWorkflowDefinition(definition, actions, conditions, receiverIndexId, keepChilds);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in AddWorkflowDefinitionWithIndex : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }

            return l_oRet;
        }

        /// <summary>
        /// Add a definition With index identifier as receivers.
        /// </summary>
        /// <param name="definition">The definition</param>
        /// <param name="actions">List of availables actions for the definition</param>
        /// <param name="conditions">List of availables conditions for the definition</param>
        /// <param name="receiversGroupIds">List of group identifier</param>
        /// <param name="keepChilds">if set to <c>true</c> [keep childs].</param>
        /// <returns>
        /// True if ok
        /// </returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean AddWorkflowDefinitionWithGroups(WorkflowDefinition definition, Dictionary<long, bool> actions, List<long> conditions, List<long> receiversGroupIds, bool keepChilds = true)
        {
            ReturnBoolean l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowDefinitionRepository.AddWorkflowDefinition(definition, actions, conditions, receiversGroupIds, keepChilds);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in AddWorkflowDefinitionWithGroups : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }

            return l_oRet;
        }

        /// <summary>
        /// Returns all actions for a definition
        /// </summary>
        /// <param name="wkfDefId">Definition identifier</param>        
        /// <returns>List of all definition actions</returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowAction> GetDefinitionActions(long wkfDefId)
        {
            var l_oRet = new List<WorkflowAction>();
            try
            {
                l_oRet = WorkflowDefinitionRepository.GetDefinitionActions(wkfDefId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowAction("Exception in GetDefinitionActions : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetDefinitionActions : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Returns all conditions for a definition
        /// </summary>
        /// <param name="wkfDefId">Definition identifier</param>
        /// <returns>List of all definition conditions</returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowCondition> GetDefinitionConditions(long wkfDefId)
        {
            var l_oRet = new List<WorkflowCondition>();
            try
            {
                l_oRet = WorkflowDefinitionRepository.GetDefinitionConditions(wkfDefId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowCondition("Exception in GetDefinitionConditions : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetDefinitionConditions : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Add an action to the definition
        /// </summary>
        /// <param name="wkfDefId">Workflow definition identifier</param>
        /// <param name="wkfActionId">The WKF action id.</param>
        /// <param name="isTrigger">True if the action is a trigger</param>
        /// <returns>
        /// True if ok
        /// </returns>
        [Invoke]
        public ReturnBoolean AddActionToDefinition(long wkfDefId, long wkfActionId, bool isTrigger)
        {
            ReturnBoolean l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowDefinitionRepository.AddActionToDefinition(wkfDefId, wkfActionId, isTrigger);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in AddActionToDefinition : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }

            return l_oRet;
        }

        /// <summary>
        /// Add a condition to the definition
        /// </summary>
        /// <param name="wkfDefId">Workflow definition identifier</param>
        /// <param name="wkfConditionId">The WKF condition id.</param>
        /// <returns>
        /// True if ok
        /// </returns>
        [Invoke]
        public ReturnBoolean AddConditionToDefinition(long wkfDefId, long wkfConditionId)
        {
            ReturnBoolean l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowDefinitionRepository.AddConditionToDefinition(wkfDefId, wkfConditionId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in AddConditionToDefinition : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }

            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow definition childs.
        /// </summary>
        /// <param name="wkfDefId">The WKF def id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowDefinition> GetWorkflowDefinitionChilds(long wkfDefId)
        {
            var l_oRet = new List<WorkflowDefinition>();
            try
            {
                l_oRet = WorkflowDefinitionRepository.GetWorkflowDefinitionChilds(wkfDefId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowDefinition("Exception in GetWorkflowDefinitionChilds : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowDefinitionChilds : " + ex.Message);
            }
            return l_oRet;
        }

        #endregion

        #region Workflow Model

        //[Query]
        //public IEnumerable<WorkflowStateInfo> GetWorkflowStateInfos()
        //{
        //    throw new NotImplementedException();
        //}

        /// <summary>
        /// Returns all models
        /// </summary>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowModel> GetWorkflowModels()
        {
            var l_oRet = new List<WorkflowModel>();
            try
            {
                l_oRet = WorkflowModelRepository.GetWorkflowModel();
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowModel("Exception in GetWorkflowModels : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowModels : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Returns model by this id.
        /// </summary>
        /// <param name="modelId">Model id</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowModel> GetWorkflowModelById(long modelId)
        {
            var l_oRet = new List<WorkflowModel>();
            try
            {
                l_oRet.Add(WorkflowModelRepository.GetWorkflowModelById(modelId));
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowModel("Exception in GetWorkflowModelById : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowModelById : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Returns model by this name.
        /// </summary>
        /// <param name="modelName">Name of the model.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowModel> GetWorkflowModelByName(string modelName)
        {
            var l_oRet = new List<WorkflowModel>();
            try
            {
                l_oRet.Add(WorkflowModelRepository.GetWorkflowModelByName(modelName));
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowModel("Exception in GetWorkflowModelByName : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowModelByName : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Add a workflow model
        /// </summary>
        /// <param name="model">Workflow model instance</param>
        /// <param name="actionsId">The actions id.</param>
        /// <param name="conditionsId">The conditions id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean AddWorkflowModel(WorkflowModel model, List<long> actionsId, List<long> conditionsId)
        {
            ReturnBoolean l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowModelRepository.AddWorkflowModel(model, actionsId, conditionsId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in AddWorkflowModel : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }

            return l_oRet;
        }

        /// <summary>
        /// Returns all actions for a model.
        /// </summary>
        /// <param name="wkfModelID">Model identifier</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowAction> GetModelActions(long wkfModelID)
        {
            var l_oRet = new List<WorkflowAction>();
            try
            {
                l_oRet = WorkflowModelRepository.GetModelActions(wkfModelID);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowAction("Exception in GetModelActions : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetModelActions : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Returns all conditions for a model.
        /// </summary>
        /// <param name="wkfModelID">Model identifier</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowCondition> GetModelConditions(long wkfModelID)
        {
            var l_oRet = new List<WorkflowCondition>();
            try
            {
                l_oRet = WorkflowModelRepository.GetModelConditions(wkfModelID); 
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowCondition("Exception in GetModelConditions : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetModelConditions : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Deletes the model.
        /// </summary>
        /// <param name="wkfModelID">The WKF model ID.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean DeleteModel(long wkfModelID)
        {
            var l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowModelRepository.DeleteModel(wkfModelID);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in DeleteModel : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the color of the workflow state.
        /// </summary>
        /// <returns></returns>
        [Query]
        public List<WorkflowStateInfo> GetWorkflowStateInfos()
        {
            var l_oRet = new List<WorkflowStateInfo>();
            try
            {
                l_oRet = WorkflowModelRepository.GetWorkflowStateInfos();
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowStateInfos : " + ex.Message);
            }
            return l_oRet;
        }

        #endregion

        #region Workflow Instance

        /// <summary>
        /// Adds the workflow instance.
        /// </summary>
        /// <param name="wkfDefinitionId">The WKF definition id.</param>
        /// <param name="folderId">The folder id.</param>
        /// <param name="userId">The user id.</param>
        /// <param name="StartingCondition">The starting condition.</param>
        /// <param name="docId">The doc id.</param>
        /// <param name="chronoId">The chrono id.</param>
        /// <param name="parentId">The parent id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnLong AddWorkflowInstance(long wkfDefinitionId, long folderId, long userId, long StartingCondition, List<long> docId, long? chronoId = 0, long? parentId = null)
        {
            ReturnLong l_oRet = new ReturnLong();

            try
            {
                WorkflowDefinition def = WorkflowDefinitionRepository.GetWorkflowDefinitionById(wkfDefinitionId);
                l_oRet.Value = WorkflowInstanceRepository.AddWorkflowInstance(def, folderId, userId, WorkflowState.Started, StartingCondition, docId, chronoId, parentId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnLong("Exception in AddWorkflowInstance : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }

            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow instances by definition id.
        /// </summary>
        /// <param name="wkfDefinitionId">The WKF definition id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]       
        public IEnumerable<WorkflowInstance> GetWorkflowInstancesByDefinitionId(long wkfDefinitionId)
        {
            var l_oRet = new List<WorkflowInstance>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetWorkflowInstancesByDefinitionId(wkfDefinitionId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstance("Exception in GetWorkflowInstancesByDefinitionId : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowInstancesByDefinitionId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow instance.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <param name="userId">The user id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowInstance> GetWorkflowInstance(long wkfInstanceId, long userId)
        {
            var l_oRet = new List<WorkflowInstance>();
            try
            {
                WorkflowInstance instance = WorkflowInstanceRepository.GetWorkflowInstance(wkfInstanceId, userId);
                l_oRet.Add(instance);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstance("Exception in GetWorkflowInstance : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowInstance : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Deletes the user instance.
        /// </summary>
        /// <param name="wkfUserInstanceId">The WKF user instance id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean DeleteUserInstance(long wkfUserInstanceId)
        {
            var l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowInstanceRepository.DeleteUserInstance(wkfUserInstanceId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in DeleteUserInstance : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }
            return l_oRet;
        }

        /// <summary>
        /// Deletes the instance.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean DeleteInstance(long wkfInstanceId)
        {
            var l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowInstanceRepository.DeleteInstance(wkfInstanceId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in DeleteInstance : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow instances by sender id.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <param name="completedInstance">The completed instance.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<WorkflowInstance> GetWorkflowInstancesBySenderId(long userId, long folderTypeId, bool completedInstance)
        {
            var l_oRet = new List<WorkflowInstance>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetWorkflowInstancesBySenderId(userId, folderTypeId, completedInstance);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstance("Exception in GetWorkflowInstancesBySenderId : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowInstancesBySenderId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow instances by receiver id.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <param name="completedInstance">The completed instance.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowInstance> GetWorkflowInstancesByReceiverId(long userId, long folderTypeId, bool completedInstance)
        {
            var l_oRet = new List<WorkflowInstance>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetWorkflowInstancesByReceiverId(userId, folderTypeId, completedInstance);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstance("Exception in GetWorkflowInstancesByReceiverId : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowInstancesByReceiverId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow instance by folder id.
        /// </summary>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <param name="folderId">The folder id.</param>
        /// <param name="userId">The user id.</param>
        /// <param name="isFolderTypeAdmin">The is folder type admin.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowInstance> GetWorkflowInstancesByFolderId(long folderTypeId, long folderId, long userId, bool? isFolderTypeAdmin = false)
        {
            var l_oRet = new List<WorkflowInstance>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetWorkflowInstancesByFolderId(folderTypeId, folderId, userId, isFolderTypeAdmin);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstance("Exception in GetWorkflowInstancesByFolderId : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowInstancesByFolderId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow instances by FLD type id.
        /// </summary>
        /// <param name="organizationId">The organization id.</param>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <param name="completedInstance">The completed instance.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowInstance> GetWorkflowInstancesByFldTypeId(long organizationId, long folderTypeId, bool completedInstance)
        {
            var l_oRet = new List<WorkflowInstance>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetWorkflowInstancesByFldTypeId(folderTypeId, completedInstance);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstance("Exception in GetWorkflowInstancesByFldTypeId : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowInstancesByFldTypeId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the instances by user id.
        /// </summary>
        /// <param name="userId">The user id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowInstance> GetWorkflowInstancesByUserId(long userId)
        {
            var l_oRet = new List<WorkflowInstance>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetWorkflowInstancesByUserId(userId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstance("Exception in GetInstancesByUserId : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetInstancesByUserId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the child workflow instance.
        /// </summary>
        /// <param name="organizationId">The organization id.</param>
        /// <param name="folderTypeId">The folder type id.</param>
        /// <param name="wkfInstanceId">The WKF def id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowInstance> GetWorkflowInstanceChilds(long organizationId, long folderTypeId, long wkfInstanceId)
        {
            var l_oRet = new List<WorkflowInstance>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetChildWorkflowInstance(folderTypeId, wkfInstanceId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstance("Exception in GetWorkflowInstanceChilds : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowInstanceChilds : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow instances count by sender id.
        /// </summary>
        /// <param name="userId">The sender id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WkfTuple> GetCompletedInstancesCountBySenderId(long userId)
        {
            var l_oRet = new List<WkfTuple>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetInstancesCountBySenderId(userId, true);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetCompletedInstancesCountBySenderId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the processing instances count by sender id.
        /// </summary>
        /// <param name="userId">The sender id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WkfTuple> GetProcessingInstancesCountBySenderId(long userId)
        {
            var l_oRet = new List<WkfTuple>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetInstancesCountBySenderId(userId, false);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetProcessingInstancesCountBySenderId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the completed instances count by receiver id.
        /// </summary>
        /// <param name="userId">The receiver id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WkfTuple> GetCompletedInstancesCountByReceiverId(long userId)
        {
            var l_oRet = new List<WkfTuple>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetInstancesCountByReceiverId(userId, true);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetCompletedInstancesCountByReceiverId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the processing instances count by receiver id.
        /// </summary>
        /// <param name="userId">The receiver id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WkfTuple> GetProcessingInstancesCountByReceiverId(long userId)
        {
            var l_oRet = new List<WkfTuple>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetInstancesCountByReceiverId(userId, false);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetProcessingInstancesCountByReceiverId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the workflow instance not readed.
        /// </summary>
        /// <returns></returns>
        [Query]
        public IEnumerable<ReturnLong> GetWorkflowInstanceNotRead()
        {
            var l_oRet = new List<ReturnLong>();
            try
            {
                User currentUser = HttpContext.Current.Session[ParameterSession.CurrentUser.szGetDescription()] as User;
                if (currentUser == null)
                    throw new Exception("The current user was not found in session!");

                l_oRet.Add(new ReturnLong(WorkflowInstanceRepository.GetWorkflowInstanceNotRead(currentUser.UserId)));
            }
            catch (Exception ex)
            {
                //NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowInstanceNotRead : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Returns all documents state by instance identifier.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public List<WorkflowItem> GetDocumentState(WorkflowInstance wkfInstanceId)
        {
            var l_oRet = new List<WorkflowItem>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetDocumentState(wkfInstanceId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowDocument("Exception in GetDocumentState : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetDocumentState : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the user instances.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowInstanceUser> GetUserInstances(long wkfInstanceId)
        {
            var l_oRet = new List<WorkflowInstanceUser>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetUserInstances(wkfInstanceId);
            }
            catch (Exception ex)
            {
                l_oRet.Add(new WorkflowInstanceUser("Exception in GetUserInstances : " + ex.Message));
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetUserInstances : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Adds the state of the document.
        /// </summary>
        /// <param name="DocumentId">The document id.</param>
        /// <param name="wkfState">State of the WKF.</param>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean AddDocumentState(long DocumentId, WorkflowState wkfState, long wkfInstanceId)
        {
            var l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowInstanceRepository.AddDocumentState(DocumentId, wkfState, wkfInstanceId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in AddDocumentState : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in AddDocumentState : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the rules by definition id.
        /// </summary>
        /// <param name="wkfDefinitionId">The WKF definition id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public Rules GetRulesByDefinitionId(long wkfDefinitionId)
        {
            var l_oRet = new Rules();
            try
            {
                var def = WorkflowDefinitionRepository.GetWorkflowDefinitionById(wkfDefinitionId);
                if (def !=null)
                    l_oRet = Rules.Deserialize(def.Rules);
                else
                    NetBay.Core.Log.LogManager.Instance().LogError("Cannot Deserialize empty rules!");
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetRulesByDefinitionId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the rules.
        /// </summary>
        /// <param name="rulesString">The rules string.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public Rules GetRules(string rulesString)
        {
            var l_oRet = new Rules();
            try
            {
                if (string.IsNullOrEmpty(rulesString))
                    l_oRet = Rules.Deserialize(rulesString);
                else
                    NetBay.Core.Log.LogManager.Instance().LogError("Cannot Deserialize empty rules!");
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetRules : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Updates the instance to readed.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean UpdateInstanceToReaded(long wkfInstanceId)
        {
            var l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowInstanceRepository.UpdateInstanceToReaded(wkfInstanceId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in UpdateInstanceToReaded : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }
            return l_oRet;
        }

        /// <summary>
        /// Updates the user instance to readed.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <param name="UserId">The user id.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean UpdateUserInstanceToReaded(long wkfInstanceId, long UserId)
        {
            var l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowInstanceRepository.UpdateUserInstanceToReaded(wkfInstanceId, UserId);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnBoolean("Exception in UpdateUserInstanceToReaded : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }
            return l_oRet;
        }

        /// <summary>
        /// Retreive all documents included in a folder
        /// </summary>
        /// <param name="folderTypeID">The folder type ID.</param>
        /// <param name="folderId">The folder id.</param>
        /// <param name="rguId">The rgu id.</param>
        /// <param name="userId">The user id.</param>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <param name="wkfState">State of the WKF.</param>
        /// <returns>
        /// List of Documents
        /// </returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<Document> GetWorkflowDocumentsByInstance(long folderTypeID, long folderId, long rguId, long userId, long wkfInstanceId, WorkflowState wkfState)
        {
            var l_oDocuments = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(folderTypeID<" + folderTypeID + ">folderId<" + folderId + ">rguId<" + rguId + ">userId<" + userId + ">wkfInstanceId<" + wkfInstanceId + ">wkfState<" + wkfState + ">)");

                l_oDocuments = WorkflowInstanceRepository.GetWorkflowDocumentsByInstance(folderTypeID, folderId, rguId, userId, wkfInstanceId, wkfState);
            }
            catch (Exception ex)
            {
                var l_oDocument = new Document("(p_lFolderTypeID<" + folderTypeID + "> p_lFolderId<" + folderId + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowDocumentsByInstance : " + l_oDocument.FullErrorMessage);
                l_oDocuments.Add(l_oDocument);
            }
            return l_oDocuments;
        }

        /// <summary>
        /// Retreive all documents included in a folder
        /// </summary>
        /// <param name="folderTypeID">The folder type ID.</param>
        /// <param name="folderId">The folder id.</param>
        /// <param name="rguId">The rgu id.</param>
        /// <param name="userId">The user id.</param>
        /// <param name="wkfUserInstanceId">The WKF user instance id.</param>
        /// <param name="wkfState">State of the WKF.</param>
        /// <returns>
        /// List of Documents
        /// </returns>
        [Query(HasSideEffects = true)]
        public IEnumerable<Document> GetWorkflowDocumentsByUser(long folderTypeID, long folderId, long rguId, long userId, long wkfUserInstanceId, WorkflowState wkfState)
        {
            var l_oDocuments = new List<Document>();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(folderTypeID<" + folderTypeID + ">folderId<" + folderId + ">rguId<" + rguId + ">userId<" + userId + ">wkfUserInstanceId<" + wkfUserInstanceId + ">wkfState<" + wkfState + ">)");

                l_oDocuments = WorkflowInstanceRepository.GetWorkflowDocumentsByUser(folderTypeID, folderId, rguId, userId, wkfUserInstanceId, wkfState);
            }
            catch (Exception ex)
            {
                var l_oDocument = new Document("(p_lFolderTypeID<" + folderTypeID + "> p_lFolderId<" + folderId + ">)", ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowDocumentsByUser : " + l_oDocument.FullErrorMessage);
                l_oDocuments.Add(l_oDocument);
            }
            return l_oDocuments;
        }

        [Invoke(HasSideEffects = true)]
        public IEnumerable<long> GetDocumentsIdsInWorkfow(List<long> documentIds)
        {
            var result = new List<long>();
            try
            {
                result = WorkflowInstanceRepository.GetDocumentsIdsInWorkfow(documentIds);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetUserInstanceDocStateByDocumentsId : " + ex.ToString());
            }
            return result;
        }

        /// <summary>
        /// Documents the has WKF instances started.
        /// </summary>
        /// <param name="documentIdentifier">The document identifier.</param>
        /// <returns></returns>
        [Invoke]
        public ReturnBoolean DocumentHasWkfInstancesStarted(long documentIdentifier)
        {
            var l_oDocuments = new ReturnBoolean();

            try
            {
                NetBay.Core.Log.LogManager.Instance().LogDebug("(documentIdentifier<" + documentIdentifier + ">");
                l_oDocuments.Value = WorkflowInstanceRepository.DocumentHasWkfInstancesStarted(documentIdentifier);
            }
            catch (Exception ex)
            {
                var l_oDocument = new ReturnBoolean(ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in DocumentHasWkfInstancesStarted : " + l_oDocument.FullErrorMessage);
            }
            return l_oDocuments;
        }

        #endregion

        #region Workflow Actions

        /// <summary>
        /// Executes the workflow action.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <param name="wkfActionId">The WKF action id.</param>
        /// <param name="rguId">The rgu id.</param>
        /// <param name="wkfDocumentStateId">The WKF document state id.</param>
        /// <param name="uiActionType">Type of the UI action.</param>
        /// <param name="actionParameters">The action parameters.</param>
        /// <param name="isGlobalAction">if set to <c>true</c> [is global action].</param>
        /// <param name="organizationIdentifier">The organization identifier.</param>
        /// <param name="folderTypeIdentifier">The folder type identifier.</param>
        /// <param name="folderIdentifier">The folder identifier.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ActionResult ExecuteWorkflowAction(long wkfInstanceId, 
            long wkfActionId, 
            long rguId, 
            List<long> wkfDocumentStateId, 
            WorkflowTypeAction uiActionType, 
            List<Parameter> actionParameters, 
            bool isGlobalAction,
            long organizationIdentifier,
            long folderTypeIdentifier,
            long folderIdentifier)
        {
            var user = GetUser();

            return WorkflowController.ExecuteAction(wkfInstanceId, wkfActionId, wkfDocumentStateId, user.UserId, rguId, uiActionType, organizationIdentifier, folderTypeIdentifier, folderIdentifier, actionParameters, isGlobalAction);
        }

        /// <summary>
        /// Gets the last receivers action.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <param name="rguId">The rgu id.</param>
        /// <param name="rdNo">The rd no.</param>
        /// <returns></returns>
        [Invoke]
        public ReturnLong GetLastReceiversAction(long wkfInstanceId, long rguId, long? rdNo)
        {
            var l_oRet = new ReturnLong();
            try
            {
                l_oRet.Value = WorkflowInstanceRepository.GetLastReceiversAction(wkfInstanceId, rguId, rdNo);
            }
            catch (Exception ex)
            {
                l_oRet = new ReturnLong("Exception in GetLastReceiversAction : " + ex.Message, ex);
                NetBay.Core.Log.LogManager.Instance().LogError(l_oRet.FullErrorMessage);
            }
            return l_oRet;
        }

        #endregion

        #region Workflow Histo

        /// <summary>
        /// Gets the workflow histo by instance id.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowHisto> GetWorkflowHistoByInstanceId(long wkfInstanceId)
        {
            var l_oRet = new List<WorkflowHisto>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetHistorical(wkfInstanceId);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowHistoByInstanceId : " + ex.Message);
                throw new Exception("Exception in GetWorkflowHistoByInstanceId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Gets the histo by doc id.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <param name="rdNo">The rd no.</param>
        /// <returns></returns>
        [Query(HasSideEffects = true)]
        public List<WorkflowHisto> GetWorkflowHistoByDocId(long wkfInstanceId, long rdNo)
        {
            var l_oRet = new List<WorkflowHisto>();
            try
            {
                l_oRet = WorkflowInstanceRepository.GetHistoByDocId(wkfInstanceId, rdNo);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in GetWorkflowHistoByDocId : " + ex.Message);
                throw new Exception("Exception in GetWorkflowHistoByDocId : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Adds the workflow historical.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <param name="rguId">The rgu id.</param>
        /// <param name="userId">The user id.</param>
        /// <param name="state">The state.</param>
        /// <param name="actionIdentifier">The action identifier.</param>
        /// <param name="documentIdentifier">The document identifier.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean AddWorkflowHistorical(long wkfInstanceId, long? rguId, long userId, WorkflowState state, long? actionIdentifier, long? documentIdentifier)
        {
            var l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowInstanceRepository.AddHistorical(wkfInstanceId, rguId, userId, state, actionIdentifier, documentIdentifier);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in AddWorkflowHistorical : " + ex.Message);
                throw new Exception("Exception in AddWorkflowHistorical : " + ex.Message);
            }
            return l_oRet;
        }

        /// <summary>
        /// Adds the workflow historical for all documents.
        /// </summary>
        /// <param name="wkfInstanceId">The WKF instance id.</param>
        /// <param name="rguId">The rgu id.</param>
        /// <param name="userId">The user id.</param>
        /// <param name="state">The state.</param>
        /// <param name="actionIdentifier">The action identifier.</param>
        /// <returns></returns>
        [Invoke(HasSideEffects = true)]
        public ReturnBoolean AddWorkflowHistoricalForAllDocuments(long wkfInstanceId, long? rguId, long userId, WorkflowState state, long? actionIdentifier)
        {
            var l_oRet = new ReturnBoolean();
            try
            {
                l_oRet.Value = WorkflowInstanceRepository.AddHistoricalForAllDocuments(wkfInstanceId, rguId, userId, state, actionIdentifier);
            }
            catch (Exception ex)
            {
                NetBay.Core.Log.LogManager.Instance().LogError("Exception in AddWorkflowHistoricalForAllDocuments : " + ex.Message);
                throw new Exception("Exception in AddWorkflowHistoricalForAllDocuments : " + ex.Message);
            }
            return l_oRet;
        }

        #endregion

    }
}